package network

import (
	"github.com/onflow/flow-go/model/flow"
	"github.com/onflow/flow-go/module/component"
	"github.com/onflow/flow-go/network/channels"
)

// Misbehavior is the type of malicious action concerning a message dissemination that can be reported by the engines.
// The misbehavior is used to penalize the misbehaving node at the protocol level concerning the messages that the current
// node has received from the misbehaving node.
type Misbehavior string

func (m Misbehavior) String() string {
	return string(m)
}

// MisbehaviorReporter is an interface that is used to report misbehavior of a remote node.
// The misbehavior is reported to the networking layer to penalize the misbehaving node.
type MisbehaviorReporter interface {
	// ReportMisbehavior reports the misbehavior of a node on sending a message to the current node that appears valid
	// based on the networking layer but is considered invalid by the current node based on the Flow protocol.
	// The misbehavior is reported to the networking layer to penalize the misbehaving node.
	// Implementation must be thread-safe and non-blocking.
	ReportMisbehavior(MisbehaviorReport)
}

// MisbehaviorReport abstracts the semantics of a misbehavior report.
// The misbehavior report is generated by the engine that detects a misbehavior on a delivered message to it. The
// engine crafts a misbehavior report and sends it to the networking layer to penalize the misbehaving node.
type MisbehaviorReport interface {
	// OriginId returns the ID of the misbehaving node.
	OriginId() flow.Identifier

	// Reason returns the reason of the misbehavior.
	Reason() Misbehavior

	// Penalty returns the penalty value of the misbehavior.
	Penalty() float64
}

// MisbehaviorReportManager abstracts the semantics of handling misbehavior reports.
// The misbehavior report manager is responsible for handling misbehavior reports that are sent by the engines.
// The misbehavior report manager is responsible for penalizing the misbehaving node and disallow-listing the node
// if the overall penalty of the misbehaving node drops below the disallow-listing threshold.
type MisbehaviorReportManager interface {
	component.Component
	// HandleMisbehaviorReport handles the misbehavior report that is sent by the engine.
	// The implementation of this function should penalize the misbehaving node and report the node to be
	// disallow-listed if the overall penalty of the misbehaving node drops below the disallow-listing threshold.
	// The implementation of this function should be thread-safe and non-blocking.
	HandleMisbehaviorReport(channels.Channel, MisbehaviorReport)
}
